#include "GUI.h"

#include <gl/gl.h>
#include <gl/glu.h>
#include <stdio.h>
#include <math.h>

#include "window.h"
#include "Font.h"

//Constructor Background GUI
GUI::GUI(int x, int y, int width, int height,int gui_type)
{
    position.x = x;
    position.y = y;
    position.width = width;
    position.height = height;

    visible     = true;
    str         = NULL;
    checked     = NULL;
    GUI_TYPE    = gui_type;
    clicked_once    = false;
}

//Constructor Label, Button & input GUI
GUI::GUI(int x, int y, int width, int height, char *string,int gui_type)
{
    position.x = x;
    position.y = y;
    position.width = width;
    position.height = height;

    visible     = true;
    str         = string;
    checked     = NULL;
    GUI_TYPE    = gui_type;
    clicked_once    = false;
}

//Contructor Checkbox GUI
GUI::GUI(int x, int y, bool new_checked,int gui_type)
{
    position.x = x;
    position.y = y;
    position.width = 32;
    position.height = 32;

    visible     = true;
    str         = NULL;
    checked     = new_checked;
    GUI_TYPE    = gui_type;
    clicked_once    = false;
}

//Destructors
GUI::~GUI()
{
    //dtor
}

//Draw The GUI element
void GUI::draw()
{
    if(MouseCoord.Left_Button == false)
    {
        clicked_once = false;
    }

    if(visible == true)
    {
    glMatrixMode(GL_PROJECTION);
        glPushMatrix();
        glLoadIdentity();
        glOrtho(0,WindowRect.width,WindowRect.height,0,0,1);

    glMatrixMode(GL_MODELVIEW);

    switch(GUI_TYPE)
    {
        //Plain Background
        case GUI_BACKGROUND:
                glPushMatrix();
                    glBegin(GL_QUADS);
                        glColor3f(0.2f, 0.2f, 0.2f);
                        glVertex2f(position.x,position.y);
                        glVertex2f(position.x + position.width,position.y);
                        glVertex2f(position.x + position.width,position.y + position.height);
                        glVertex2f(position.x,position.y + position.height);

                        glColor3f(0.4f, 0.4f, 0.4f);
                        glVertex2f(position.x+2,position.y+2);
                        glVertex2f((position.x+position.width)-2,position.y+2);
                        glVertex2f((position.x+position.width)-2,(position.y + position.height)-2);
                        glVertex2f(position.x+2,(position.y + position.height)-2);

                        glColor3f(0.2f, 0.2f, 0.2f);
                        glVertex2f(position.x+4,position.y+4);
                        glVertex2f((position.x+position.width)-4,position.y+4);
                        glVertex2f((position.x+position.width)-4,(position.y + position.height)-4);
                        glVertex2f(position.x+4,(position.y + position.height)-4);
                    glEnd();
                glPopMatrix();
        break;

        case GUI_LABEL:
            if(str != NULL)
            {
                glColor3f(0.4f, 0.4f, 0.4f);
                float x_center = (float)(strlen(str)-1)/2;
                x_center = x_center * 13;
                Courier->Draw(str,((position.width/2)+position.x)-x_center,((position.height/2)+position.y) + 4);
            }
        break;

        //Plain GUI Button
        case GUI_BUTTON:
            glPushMatrix();
                glBegin(GL_QUADS);
                    glColor3f(0.2f, 0.2f, 0.2f);
                    glVertex2f(position.x,position.y);
                    glVertex2f(position.x + position.width,position.y);
                    glVertex2f(position.x + position.width,position.y + position.height);
                    glVertex2f(position.x,position.y + position.height);

                    glColor3f(0.4f, 0.4f, 0.4f);
                    glVertex2f(position.x+2,position.y+2);
                    glVertex2f((position.x+position.width)-2,position.y+2);
                    glVertex2f((position.x+position.width)-2,(position.y + position.height)-2);
                    glVertex2f(position.x+2,(position.y + position.height)-2);

                    glColor3f(0.2f, 0.2f, 0.2f);
                    glVertex2f(position.x+4,position.y+4);
                    glVertex2f((position.x+position.width)-4,position.y+4);
                    glVertex2f((position.x+position.width)-4,(position.y + position.height)-4);
                    glVertex2f(position.x+4,(position.y + position.height)-4);
                glEnd();
            glPopMatrix();

            if(str != NULL)
            {
                glColor3f(0.4f, 0.4f, 0.4f);
                float x_center = (float)(strlen(str)-1)/2;
                x_center = x_center * 13;
                Courier->Draw(str,((position.width/2)+position.x)-x_center,((position.height/2)+position.y) + 4);
            }
        break;

        //Plain GUI Checkbox
        case GUI_CHECKBOX:
            glPushMatrix();
                glBegin(GL_QUADS);
                    glColor3f(0.2f, 0.2f, 0.2f);
                    glVertex2f(position.x,position.y);
                    glVertex2f(position.x + position.width,position.y);
                    glVertex2f(position.x + position.width,position.y + position.height);
                    glVertex2f(position.x,position.y + position.height);

                    glColor3f(0.4f, 0.4f, 0.4f);
                    glVertex2f(position.x+2,position.y+2);
                    glVertex2f((position.x+position.width)-2,position.y+2);
                    glVertex2f((position.x+position.width)-2,(position.y + position.height)-2);
                    glVertex2f(position.x+2,(position.y + position.height)-2);

                    glColor3f(0.2f, 0.2f, 0.2f);
                    glVertex2f(position.x+4,position.y+4);
                    glVertex2f((position.x+position.width)-4,position.y+4);
                    glVertex2f((position.x+position.width)-4,(position.y + position.height)-4);
                    glVertex2f(position.x+4,(position.y + position.height)-4);
                glEnd();

                if(checked == true)
                {
                    glLineWidth(3);
                    glBegin(GL_LINES);
                        glColor3f(0.4f, 0.4f, 0.4f);
                        glVertex2f(position.x + 7, position.y + 7);
                        glVertex2f((position.x + position.width) - 7,(position.y + position.height) - 7);

                        glVertex2f(position.x+7,(position.y+position.height) - 7);
                        glVertex2f((position.x+position.width) - 7,position.y+7);
                    glEnd();
                    glLineWidth(1);
                }
            glPopMatrix();
        break;
    }

    glMatrixMode(GL_PROJECTION);
        glPopMatrix();
    glMatrixMode(GL_MODELVIEW);
        glPopMatrix();
    }

}

//Hide GUI stuff
void GUI::Hide()
{
    visible = false;
}

//Show GUI stuff
void GUI::Show()
{
    visible = true;
}

//Return if the GUI element is visisble
bool GUI::Visible()
{
    return visible;
}

//Return if mouse hovers over the GUI element
bool GUI::MouseOver()
{
    if(MouseCoord.mouseX >= position.x &&
       MouseCoord.mouseX <= position.x + position.width &&
       MouseCoord.mouseY >= position.y &&
       MouseCoord.mouseY <= position.y + position.height &&
       visible)
   {
       return true;
   }
   else
   {
       return false;
   }
}

//Return true if the GUI element is clicked
bool GUI::Clicked()
{
    if(MouseCoord.mouseX >= position.x &&
       MouseCoord.mouseX <= position.x + position.width &&
       MouseCoord.mouseY >= position.y &&
       MouseCoord.mouseY <= position.y + position.height &&
       MouseCoord.Left_Button && visible &&
       clicked_once == false)
   {
       if(GUI_TYPE == GUI_CHECKBOX && checked == true && clicked_once == false)
       {
           checked = false;
       }
       else if(clicked_once == false)
       {
           checked = true;
       }
       clicked_once = true;
       return true;
   }
   else
   {
       return false;
   }
}

//Constructor for GUI linked list
GUI_LIST::GUI_LIST()
{
    Parrent = NULL;
    Child   = NULL;
    Self    = NULL;
}

//Construct GUI list with first GUI element.
GUI_LIST::GUI_LIST(GUI *New_Self)
{
    Parrent = NULL;
    Child = NULL;
    Self = New_Self;
}

//Update the GUI list - cal the draw function from the GUI
void GUI_LIST::Update()
{
    Self->draw();

    GUI_LIST *tmp = Child;
    while(tmp != NULL)
    {
        tmp->Self->Clicked();
        tmp->Self->draw();
        tmp = tmp->Child;
    }
}

//Show the GUI elements in the GUI list
void GUI_LIST::Show()
{
    Self->Show();
    GUI_LIST *tmp = Child;
    while(tmp != NULL)
    {
        tmp->Self->Show();
        tmp = tmp->Child;
    }
}

//Hide the GUI elements in the GUI list
void GUI_LIST::Hide()
{
    Self->Hide();
    GUI_LIST *tmp = Child;
    while(tmp != NULL)
    {
        tmp->Self->Hide();
        tmp  = tmp->Child;
    }
}

//Append a new GUI element to the draw list
void GUI_LIST::Append(GUI *New_GUI)
{
    if(Self != NULL)
    {
        if(Child != NULL)
        {
            GUI_LIST *tmp = Child;
            while(tmp->Child != NULL)
            {
                tmp = tmp->Child;
            }
            tmp->Child = new GUI_LIST(New_GUI);
        }
        else
        {
            Child = new GUI_LIST(New_GUI);
        }
    }
    else
    {
        Self = New_GUI;
    }
}
